package cs423.loadBalancer.core;

public class Adaptor implements Runnable{

	@Override
	public void run() {

		Thread wm = new Thread(new waitOnMonitor());
		Thread ws = new Thread(new waitOnState());
		
		wm.setDaemon(true);
		ws.setDaemon(true);
		
		System.out.println("THREADS INSIDE ADAPTOR CREATED SUCCESFULLY");

		
		wm.start();
		ws.start();
		
		
		try {
			//Main.a.lock();
			Main.a_cv.acquire();
			
		} catch (InterruptedException e) {
			e.printStackTrace();
			System.out.println("Main.a_cv.acquire();");

		} finally {
			System.out.println("FORCE CLOSE ALL THREADS IN ADAPTOR");
			wm.stop();
			ws.stop();
		}
		
	}
	//This thread waits on the state thread
	class waitOnState implements Runnable{

		@Override
		public void run() {
			
			while(true){
			//wait on cv state_tri_adaptor_s-a
			try {
				//Main.state_tri_adaptor_s_a_lock.lock();
				Main.state_tri_adaptor_s_a_cv.acquire();
			} catch (InterruptedException e) {
				e.printStackTrace();
				System.out.println("Main.state_tri_adaptor_s_a_cv.await();");
			}// finally {
				//Main.state_tri_adaptor_s_a_lock.unlock();
			//}
			
			//analyse if accepting job is possible
			double my_percentage = Main.cut_pos.size()/(double)Main.initial_q_size;
			if(my_percentage<Main.other_percentage &&
					(Math.abs(my_percentage-Main.other_percentage)/my_percentage) > 0.05&&!Main.other_side_closed) {
					//accept/deny by writing to the shared variable
					Main.passive_transfer_decision=(int)(Math.abs((Main.other_percentage-my_percentage)/1.6)*Main.initial_q_size);
					
					}
			else 
					Main.passive_transfer_decision = Main.BUCHUAN;
			
			//post another cv to let the state manager know that
			//decision has been made
			Main.state_tri_adaptor_a_s_cv.release();
			}
			
		}
		
	}

	//this threads waits on the Monitor thread
	class waitOnMonitor implements Runnable{

		@Override
		public void run() {
			while(true){
				//wait on monitor notice
				try {
					//Main.adaptor_monitor_lock.lock();
					Main.monitor_w_adaptor.acquire();
				} catch (InterruptedException e) {
					e.printStackTrace();
					System.out.println("Main.monitor_w_adaptor.await();");
				} //finally {
					//Main.adaptor_monitor_lock.unlock();
				//}
				
				//access shared CPU and THROTTLE INFO
				float current_cpu = Main.cpu_usage;
				int current_throttle = Main.throttle;
				
				//analyse
				System.out.println("AD: THROTTLE:  "+current_throttle);
				System.out.println("AD: CPU:  "+current_cpu);
				
				
				if((current_throttle>40||current_cpu>60)&&Main.cut_pos.size()>TransferManager.transferAmount*1.7&&!Main.other_side_closed){
					
					System.out.println("ACTIVE PASSING JOBS IN ADAPTOR");
					//INFORM STATE MANAGER THROUGH COMMON CV, 
					Main.adaptor_tri_state_a_s_cv.release();
				
					//WAIT ON THE CV THAT WAITS FOR THE RESPONSE
					try {
						//Main.adaptor_tri_state_s_a_lock.lock();
						Main.adaptor_tri_state_s_a_cv.acquire();
					} catch (InterruptedException e) {						
						e.printStackTrace();
						System.out.println("Main.adaptor_tri_state_s_a_cv.await();z");
					}// finally {
						//Main.adaptor_tri_state_s_a_lock.unlock();
					
					//}
				
					if(Main.active_transfer_decision>0)
					{
						TransferManager.transferAmount=Main.active_transfer_decision;
						System.out.println("SET TRANSFER AMT: " + TransferManager.transferAmount);
						Main.displayHandler.post(new Runnable(){
							public void run(){
								Main.updateTransferAmount();
							}
						})	;			
						Main.trans_w_adaptor.release();
					}
				}
					
					
				//do other action
					//INFORM WORKER THREAD IF THROTTLE CHANGES OR MAYBE CPU
					//-> SHOULD NOTIFY THE CV THAT IS BETWEEN ADAPTOR AND 
					//WORKER THREAD
					//Main.adaptor_worker_cv.signal();
					//NEED OR NOT??????????????????????????????
				
				
			}	
			
		}
		
	}

}
